package com.fengchao.controller;

import com.alibaba.fastjson.JSON;
import com.fengchao.service.PayService;
import com.fengchao.util.MailTools;
import com.fengchao.util.XMLUtil;
import com.fengchao.util.alipay.AlipayNotifyUtil;
import com.fengchao.util.weixin.WeixinUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.sound.midi.MidiDevice;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;

/**
 * Created by wangnian on 2016/7/21.
 */
@RestController
@RequestMapping("/pay")
public class PayController {
    @Autowired
    private PayService payService;
    @Autowired
    MailTools mailTools;
    //http://notify.java.jpxx.org/index.jsp?discount=0.00&payment_type=1&subject=测试&trade_no=2013082244524842&buyer_email=dlwdgl@gmail.com&gmt_create=2013-08-22 14:45:23&notify_type=trade_status_sync&quantity=1&out_trade_no=082215222612710&seller_id=2088501624816263&notify_time=2013-08-22 14:45:24&body=测试测试&trade_status=TRADE_SUCCESS&is_total_fee_adjust=N&total_fee=1.00&gmt_payment=2013-08-22 14:45:24&seller_email=xxx@alipay.com&price=1.00&buyer_id=2088602315385429&notify_id=64ce1b6ab92d00ede0ee56ade98fdf2f4c&use_coupon=N&sign_type=RSA&sign=1glihU9DPWee+UJ82u3+mw3Bdnr9u01at0M/xJnPsGuHh+JA5bk3zbWaoWhU6GmLab3dIM4JNdktTcEUI9/FBGhgfLO39BKX/eBCFQ3bXAmIZn4l26fiwoO613BptT44GTEtnPiQ6+tnLsGlVSrFZaLB9FVhrGfipH2SWJcnwYs=
    private static Logger logger = LoggerFactory.getLogger(PayController.class);

    /**
     * 支付宝异步的通知
     */
    @RequestMapping(value = "/alipay/asynchronousNotify", method = RequestMethod.POST)
    public String alipayNotify(HttpServletRequest request) throws UnsupportedEncodingException {
        logger.info("支付宝回调地址请求参数=requst:{}", JSON.toJSON(request.getParameterMap()));
        //获取支付宝POST过来反馈信息)
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        if (request.getParameter("out_trade_no") == null || request.getParameter("trade_no") == null || request.getParameter("trade_status") == null || request.getParameter("buyer_email") == null || request.getParameter("total_fee") == null) {
            logger.warn("非法请求,没有带参数");
            return "error";
        }

        //商户订单号
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
        //支付账号
        String buyer_email = new String(request.getParameter("buyer_email").getBytes("ISO-8859-1"), "UTF-8");
        //支付的金额
        BigDecimal total_fee = new BigDecimal(request.getParameter("total_fee"));//支付宝原样返回  1.00
        String refund_status = request.getParameter("refund_status");//支付宝退款字段
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        if (AlipayNotifyUtil.verify(params)) {//验证成功
            if (trade_status.equals("TRADE_FINISHED")) {
                logger.info("支付失败= 订单号:{},支付宝交易号:{}", out_trade_no, trade_no);
                payService.payFailure(out_trade_no, 1, buyer_email, trade_no);//支付失败记录
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                if (refund_status != null) {
                    logger.info("退款成功= 订单号:{},支付宝交易号:{}", out_trade_no, trade_no);
                    return "success";
                }
                logger.info("支付成功= 订单号:{},支付宝交易号:{}", out_trade_no, trade_no);
                Boolean bool = payService.paySucceed(out_trade_no, 1, buyer_email, trade_no, total_fee); //记录支付
                if (bool) {
                    payService.orderSuccessDispose(out_trade_no); //修改
                }
            }
        } else {//验证失败
            logger.warn("验证失败= 订单号:{},支付宝交易号:{}", out_trade_no, trade_no);
        }
        return "success";
    }

    /**
     * 微信回调地址
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/weixin/asynchronousNotify", method = RequestMethod.POST)
    public String wexinNotify(HttpServletRequest request) {
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String resultStr = new String(outSteam.toByteArray(), "utf-8");
            SortedMap<String, String> resultMap = XMLUtil.doXMLParse(resultStr);//将xml转成排序之后的map
            logger.info("微信支付回调地址请求参数=requst:{}", JSON.toJSON(resultMap));
            String result_code = resultMap.get("result_code");//业务结果
            String is_subscribe = resultMap.get("is_subscribe");//是否关注了微信公众号
            String out_trade_no = resultMap.get("out_trade_no");//订单号
            String transaction_id = resultMap.get("transaction_id");//微信支付订单号  类似于支付宝的交易号
            String sign = resultMap.get("sign");//签名
            String total_fee = resultMap.get("total_fee");//订单总金额  单位为 分
            String openid = resultMap.get("openid");//用户在商户appid下的唯一标识
            String time_end = resultMap.get("time_end");
            String bank_type = resultMap.get("bank_type");
            //签名验证
            String signStr = WeixinUtil.createSign("UTF-8", resultMap);
            logger.warn("验证= signStr:{},sign:{}", signStr, sign);
            if (!signStr.equals(sign)) {
                logger.warn("微信支付回调地址请求参数签名验证失败= signStr:{},sign:{}", signStr, sign);
                mailTools.SendMail("微信支付回调地址请求参数签名验证失败", "signStr:" + signStr + ",sign:" + sign, null);
                return "error";
            }
            if (result_code.equals("SUCCESS")) {
                logger.info("支付成功= 订单号:{},支付宝交易号:{}", out_trade_no, transaction_id);
                BigDecimal bigDecimal_total_fee = new BigDecimal(total_fee);
                BigDecimal bigDecimal = bigDecimal_total_fee.divide(new BigDecimal(100));
                Boolean bool = payService.paySucceed(out_trade_no, 2, openid, transaction_id, bigDecimal); //记录支付
                if (bool) {
                    payService.orderSuccessDispose(out_trade_no);//修改
                }
            }
            //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
            return WeixinUtil.resultSuccess();
        } catch (Exception ex) {
            logger.warn("微信支付回调地址处理异常:{}", ex);
            mailTools.SendMail("环境异常,微信支付回调地址处理异常", "异常", ex);
            ex.printStackTrace();
        }
        return "success";
    }


}

